import { createApp, h, ref } from "vue";
import { ElMessage } from "element-plus";
import BaseDialog from "./baseDialog.vue";

/**
 * @name 协助统一创建dialog组件，并且进行挂载、销毁、上报
 * @param {import('vue').Component} ContentComponent 渲染的组件
 * @param {import('element-plus').dialogProps} dialogProps dialog组件的props
 * @returns {Promise<any>}
 */
export function dialogWithComponent(ContentComponent, dialogProps = {}) {
    return new Promise((resolve) => {
      /** @name 挂载容器 */
      const container = document.createElement("div");
      document.body.appendChild(container);
      /** @name dialog组件实例 */
      let vm = null;
      /** @name dialog组件loading */
      let loading = ref(false);
      const dialogRef = ref(null);
      const contentRef = ref(null);

      const unmount = () => {
        if (vm) {
          vm.unmount();
          vm = null;
        }
        document.body.removeChild(container);
      };
      const confirm = async () => {
        let result = {};
        const instance = contentRef.value;
        if (instance && instance.getValue) {
          loading.value = true;
          try {
                result = await instance.getValue();
          } catch (error) {
                typeof error === "string" && ElMessage.error(error);
                loading.value = false;
                return;
          }
          loading.value = false;
        }
        unmount();
        resolve(result);
      };

      // 创建dialog组件实例
      vm = createApp({
        render() {
          return h(
            BaseDialog,
            {
              ref: dialogRef,
              modelValue: true,
              loading: loading.value,
              onDialogConfirm() {
                confirm();
              },
              onDialogCancel() {
                unmount();
              },
              ...dialogProps,
            },
            {
              default: () => createVNode(h, ContentComponent, contentRef),
            },
          );
        },
      });

      // 挂载dialog组件
      vm.mount(container);
    });
}

/**
* @name 创建一个 VNode 实例
* @param {import('vue').CreateElement} h Vue 的 createElement 函数
* @param {Function|Element} Component 渲染的组件或渲染函数
* @param {string} key VNode 的 key
* @param {import('vue').Ref} ref 组件引用
* @returns {import('vue').VNode|null} 返回 VNode 实例或 null
*/
export function createVNode(_h, Component, _ref = null) {
    if (!Component) return null;
    /** @type { import('vue').VNode } */
    let instance = null;
    /** @name 升级h函数，统一混入ref **/
    const render = (type, props = {}, children) => {
      return _h(
        type,
        {
          ...props,
          ref: (el) => {
            if (_ref) _ref.value = el;
          },
        },
        children,
      );
    };
    if (typeof Component === "function") {
      instance = Component(render);
    } else {
      instance = render(Component);
    }
    return instance;
}
